<template>
  <div style="height:100%">
    <div class="page-body">
      <div class="page-header" v-if="headerBtn.length > 0 || $slots.headerBtn || $slots.headerBtnLeft">
        <slot name="headerBtnLeft"></slot>
        <template v-for="item in headerBtn">
          <el-input v-if="item == 'search'" :size="butonSize" placeholder="请输入查询字段" class="page-header-query"
            :model-value="searchValue" @update:model-value="emit('update:searchValue', $event)"
            @keyup.enter.native="onSearch">
            <template #append>
              <el-button :icon="Search" @click="onSearch"></el-button>
            </template>
          </el-input>
          <el-button v-else-if="item == 'add'" :size="butonSize" type="primary" style="margin-left:12px"
            @click="onClickAdd">{{ headerBtnName.add }}
          </el-button>
          <el-button v-else-if="item == 'delete'" :size="butonSize" type="danger" :disabled="selectList.length == 0"
            @click="onClickDelete">{{ headerBtnName.delete }}</el-button>
        </template>
        <div style="flex-grow: 1;">
          <slot name="headerBtn"></slot>
        </div>
      </div>
      <div class="page-content">
        <div v-if="$slots.content" class="page-contentdata" style="padding:1px">
          <div class="page-contentdata-none" v-if="modelValue.length == 0">暂无数据</div>
          <slot v-for="item in modelValue" name="content" :data-item="item">
          </slot>
        </div>

        <el-table v-else ref="multipleTableRef" :data="thisValue" height="100%" border size="small"
          :row-class-name="rowClassName" :highlight-current-row="true" :default-expand-all="true" :row-key="props.rowKey"
          @selection-change="onSelectionChange" @select="onSelect" @cell-dblclick="rowDblclick" @cell-click="rowclick">
          <slot></slot>
        </el-table>

      </div>
      <div class="page-footer" v-if="currentPage > 0">
        <el-pagination v-model:currentPage="thisCurrentPage" background :layout="layout" :total="props.total"
          :page-size="pageSize" :small="paginationSmall"></el-pagination>
        <!-- <div class="page-footer-right">
          显示{{ (currentPage - 1) * pageSize + 1 }}-{{ Math.min(total, currentPage * pageSize) }}条
        </div> -->
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  name: "DataView",
})
</script>

<script lang="ts" setup>
import { ref, withDefaults, computed } from "vue";
import { Search } from '@element-plus/icons-vue'
import { ElMessage } from "element-plus";
let props = withDefaults(defineProps<{
  /**
   * 数据列表
   */
  modelValue: any[];
  /**
   * 搜索内容
   */
  searchValue?: string;
  /**
   * 当前页数
   * 默认为0 , 为0 的时候不启动分页功能
   */
  currentPage?: number;
  /**
   * 总数据量
   */
  total?: number;
  /**
   * 顶部按钮
   * search:搜索
   * add :新增
   * delete 删除
   */
  headerBtn?: string[];
  /**
   * 顶部按钮名称
   */
  headerBtnName?: {
    add: string,
    delete: string
  };
  /**
   * 每页加载数据
   */
  pageSize?: number;

  /**
   * 分页组件是否使用小号
   */
  paginationSmall?: boolean;

  /**
   * 行Id
   */
  rowKey?: any;
  /**
   * 行高亮
   */
  highlightCurrentRow?: boolean;

  /**
   * 行样式
   */
  rowClassName?: string | ((data: { row: any; rowIndex: number; }) => string) | undefined;

  /**
   * 行数据
   */
  expandRoweys?: any
  /**
   * 删除之前
   */
  deleteBefore?: ((selectList: any[]) => Promise<void>) | undefined
  /**
   * 按钮大小
   */
  butonSize?: "default" | "small" | "large" | undefined,

  /**
   * 组件布局，子组件名用逗号分隔
   */
  layout?: string;
}>(), {
  modelValue: () => [],
  currentPage: 0,
  total: 0,
  pageSize: 25,
  rowKey: null,
  headerBtn: () => [],
  searchValue: "",
  highlightCurrentRow: undefined,
  expandRoweys: null,
  rowClassName: "",
  paginationSmall: false,
  headerBtnName: () => {
    return {
      add: "新增",
      delete: "删除"
    }
  },
  butonSize: undefined,
  layout: "total,prev, pager, next,jumper"
})



let emit = defineEmits<{
  (e: "update:modelValue", value: any[]): void;
  /**
   * 更改搜索内容的时候
   */
  (e: "update:searchValue", value: string): void;
  /**
   * 更改当前页数
   */
  (e: "update:currentPage", value: number): void;
  /**
 * 当搜索的时候
 */
  (e: "search"): void;
  /**
   * 当点击新增的时候
   */
  (e: "clickAdd"): void;
  /**
   * 当删除成功的时候
   */
  (e: "deleteSubmit", value: any): void
  /**
   * 双击单元行的时候
   */
  (e: "dblclick", value: any): void
  /**
  * 单击单元行的时候
  */
  (e: "click", value: any, column: any): void
  /**
   * 当选项发生变化时
   */
  (e: "selectionChange", value: any): void
  (e: "select", value: any, row: any): void

}>();


let thisValue = computed({
  get() { return props.modelValue },
  set(value: any[]) {
    emit("update:modelValue", value);
  }
})
/**
 * ====================
 *  顶部按钮
 * ====================
 */

/**
 * 当进行搜索的时候
 */
function onSearch() {
  if (props.searchValue.length == 1) {
    ElMessage.warning("请输入两位以上搜索内容")
  } else {
    emit("search");
  }
}

/**
 * 点击新增的时候
 */
function onClickAdd() {
  emit("clickAdd")
}

/**
 * 点击顶部删除按钮的时候
 */
function onClickDelete() {
  if (props.deleteBefore) {
    props.deleteBefore(selectList.value)
      .then(() => {
        emit("deleteSubmit", selectList.value)
      })
  } else {
    //执行默认删除 , 删除当前展示数据
    deleteSelectRow();
  }
}

/**
 * ====================
 *  表格
 * ====================
 */

/**
 * 多选选中的数据
 */
let selectList = ref<any[]>([]);

/**
 * 当点击多选项目的时候
 */
function onSelectionChange(selection: any[]) {
  emit("selectionChange", selection)
  selectList.value = selection;
}

function onSelect(selection: any[], row: any) {
  emit("select", selection, row)
}

/**
 * 当双击行信息的时候
 */
function rowDblclick(row: any, column: any, event: any) {
  emit("dblclick", row);
}
/**
 * 当单击行信息的时候
 */
function rowclick(row: any, column: any, event: any) {
  emit("click", row, column);
}

/**
 * 删除选中行
 */
function deleteSelectRow() {
  thisValue.value = thisValue.value.filter(item => {
    return selectList.value.findIndex(item2 => item2 == item) < 0;
  })
}

let multipleTableRef = ref()
// function setToggleRowSelection(value: any) {
//   console.log("setToggleRowSelection", value);
//   console.log("thisValue.value", props.modelValue);
//   value.forEach((key: any) => {
//     thisValue.value.forEach((row: any) => {
//       if (row.Id == key) {
//         multipleTableRef.value.toggleRowSelection(row, true);
//       }
//     })
//   })
// }
/**
 * 用于多选表格，切换某一行的选中状态， 如果使用了第二个参数，则可直接设置这一行选中与否
 */
function toggleRowSelection(row: any, selected: any) {
  multipleTableRef.value.toggleRowSelection(row, selected);
}
/**
 * 用于多选表格，切换某一行的选中状态， 如果使用了第二个参数，则可直接设置这一行选中与否
 */
function setCurrentRow(row: any) {
  multipleTableRef.value.setCurrentRow(row);
}
//返回当前选中的行
function getSelectionRows() {
  multipleTableRef.value.getSelectionRows;
}
defineExpose({
  toggleRowSelection,
  getSelectionRows,
  setCurrentRow
})
/**
 * ====================
 *  分页组件
 * ====================
 */

let thisCurrentPage = computed<number>({
  get() { return props.currentPage },
  set(value: number) {
    emit("update:currentPage", value)
  }
})
</script>

<style lang="less" scoped>
.page-body {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  background-color: white;

  /deep/ .el-scrollbar__bar.is-horizontal {
    height: 10px !important;
  }
}

.page-header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  padding: 5px 0;
}

.page-header-query {
  margin-left: 10px;
  width: 200px;
}

.page-content {
  height: 0;
  flex-grow: 1;
}

.page-contentdata {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  height: 100%;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  overflow: auto;
}

.page-contentdata-none {
  width: 100%;
  height: 100%;
  color: var(--el-text-color-secondary);
  line-height: 60px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.page-footer {
  flex-shrink: 0;
  padding: 5px 0;
  padding-left: 5px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.page-footer-right {
  font-size: 13px;
}

/deep/ .classColor {
  color: red !important;
}
</style>

